package cn.pdy.try_method.jdk.java.Collection;

import org.junit.Test;

import java.util.ArrayDeque;
import java.util.LinkedList;
import java.util.PriorityQueue;

/**
 * Queue接口, 用于模拟队列数据结构, 先进先出
 * 实现类 : PriorityQueue
 * 子接口 : Deque -- 代表一个双端队列,可以同时从两端添加删除,所以也可以当成栈使用
 * Deque 的实现类 : ArrayDeque , LinkedList
 */
public class QueueTest {

    /**
     * PriorityQueue : 保存元素的顺序不是按加入队列的顺序,而是按队列元素的大小进行重新排序
     * 不允许为null
     * 不是一个绝对标准的队列
     */
    @Test
    public void test1(){
        PriorityQueue pq = new PriorityQueue();
        pq.add(6);
        pq.add(-1);
        pq.add(20);
        pq.add(18);
        System.out.println(pq);
        //获取队列头元素并删除
        System.out.println(pq.poll());
        System.out.println(pq);
    }

    /**
     * Deque 定义了一些双端队列的方法 ,还可以当成栈使用 ,包含pop,push方法
     * 实现类 : ArrayDeque
     * 创建Deque时可以指定长度, 默认底层数组长度为 16
     */
    @Test
    public void test2(){
        ArrayDeque stack = new ArrayDeque();
        // --------当成栈使用---------
        // 依次将三个元素push入栈
        stack.push("疯狂java");
        stack.push("轻量级java");
        stack.push("疯狂ios");
        // 访问第一个元素但不出栈
        System.out.println(stack.peek());
        // pop出第一个元素
        System.out.println(stack.pop());

        // ---------当成队列使用---------
        ArrayDeque queue = new ArrayDeque();
        // 依次将三个元素push入栈
        queue.offer("疯狂java");
        queue.offer("轻量级java");
        queue.offer("疯狂ios");
        // 访问队列头部元素,但不poll出队列
        System.out.println(queue.peek());
        // poll出第一个元素
        System.out.println(queue.poll());
    }

    /**
     * LinkedList 实现了 Deque 和 List
     * 内部以链表形式来保存元素, 插入和删除性能出色, 查找性能较差
     */
    @Test
    public void test3(){
        LinkedList list = new LinkedList();
        // 向队列尾部加数据
        list.offer("2");
        // 向栈顶部加数据
        list.push("333");
        // 将字符串数据加到队列头部(插队
        list.offerFirst("111");
        // 以list的方式来遍历集合(按索引访问
        for (int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
        // 访问, 不删除元素
        System.out.println(list.peekFirst());
        // 访问, 不删除队列的最后一个元素
        System.out.println(list.peekLast());
        // 将栈顶元素弹出
        System.out.println(list.pop());
        // 访问并删除队列的最后一个元素
        System.out.println(list.pollLast());
    }

    /**
     * 各种线性表的性能分析 :
     *  java提供的List就是一个线性表接口 , ArrayList ,LinkedList 是线性表的两种典型实现: 基于数组,基于链表
     *  Queue 代表了队列, Deque 代表了双端队列
     *  LinkedList 不仅提供了List的功能, 还提供了双端队列, 栈的功能.
     *  数组在随机访问时性能最好, 链表在执行插入,删除操作时有姣好的性能. 但总的来说ArrayList 比 LinkedList性能要好
     *  总结 : 大部分时候都应该考虑使用ArrayList
     *
     *  如果需要遍历List集合元素, 基于数组的应该使用随机访问方法 get 来遍历, 基于链表的应该采用迭代器
     */

}
